import logging
import random

from django.http import HttpResponse, JsonResponse
from django.views import View

from django_redis import get_redis_connection

from libs.captcha.captcha import captcha
from libs.yuntongxun.sms import CCP

logger = logging.getLogger('django')

# 1. 定义一个生成图片验证码的类视图
class ImageCodeView(View):
    def get(self, request, uuid):
        # 1. 生成图片验证码   ('Q4OH', b'\xff\xd8\xf')
        text, image =  captcha.generate_captcha()
        # 2. 在redis中存储映射关系
        conn = get_redis_connection('code')
        conn.setex('img_{}'.format(uuid), 300, text)
        # 3. 返回图片验证码
        return HttpResponse(image, content_type='image/jpeg')


# 2. 定义发送短信验证码的类视图
class SmsCodeView(View):
    def get(self, request, mobile):
        # 1. 获取参数: 用户填写的图片验证码和图片验证码的标识
        # /sms_codes/18390839708/?image_code=hwcs&image_code_id=3e0cfbce-5802-4793-a938-bc5bdd46416a
        image_code_user = request.GET.get('image_code')
        image_code_id = request.GET.get('image_code_id')
        print(image_code_user, image_code_id)

        # 2. 校验参数：要求参数不能为空
        if not all([image_code_user, image_code_id]):
            return JsonResponse({'code': 400, 'errmsg': '用户填写的图片验证码和唯一标识不能为空'})

        # 3. 比对图片验证码
        # 3.1 获取生成图片验证码时存储的图片验证码
        conn = get_redis_connection('code')
        image_code_redis = conn.get('img_{}'.format(image_code_id))
        # 3.2 如果没有则代表图片验证码已经过期了，提示错误信息
        if not image_code_redis:
            return JsonResponse({'code': 400, 'errmsg': '图片验证码已失效'})
        # 3.3 如果有则解码成字符串，和用户填写的做对比，不相同则证明用户填写错误
        image_code_redis = image_code_redis.decode()
        if image_code_user.lower() != image_code_redis.lower():
            return JsonResponse({'code': 400, 'errmsg': '图片验证码错误'})
        # 3.4 相同则删除存储的图片验证码，因为接下来要发送短信了
        try:
            conn.delete('img_{}'.format(image_code_id))
        except Exception as err:
            logger.info(err)

        # 4. 发送短信验证码
        ccp = CCP()
        # 注意： 测试的短信模板编号为1
        # 4.0 判断是是不是已经发过短信
        send_flag = conn.get('send_flag_{}'.format(mobile))
        if send_flag:
            return JsonResponse({'code': 400, 'errmsg': '在2分钟内发过短信验证码，请稍后再试'})
        # 4.1 生成短信验证码
        sms_code = str(random.randint(1000, 9999))
        # 4.2 把手机和短信验证码的对应关系存储在redis中，方便注册时进行验证
        # conn.setex('send_flag_{}'.format(mobile), 120, 1)
        # conn.setex('mobile_{}'.format(mobile), 300, sms_code)
        # 创建Redis管道
        pl = conn.pipeline()
        # 将Redis请求添加到队列
        pl.setex('send_flag_{}'.format(mobile), 120, 1)
        pl.setex('mobile_{}'.format(mobile), 300, sms_code)
        # 执行请求
        pl.execute()

        # 4.3 发送短信验证码
        ccp.send_template_sms(mobile, [sms_code, 5], 1)

        # 5. 返回发送成功的结果
        return JsonResponse({'code':0, 'errmsg': '发送验证码短信成功'})
